#ifndef __TASK_H_
#define __TASK_H_

#ifdef __cplusplus
extern "C" {
#endif

#include <common.h>
#include <queue.h>


typedef void (*TASK_FUNC)(void);

// 任务优先级
typedef enum E_TASK_PRI
{
    E_TASK_PRI0 = 240,
    E_TASK_PRI1 = 241,
    E_TASK_PRI2 = 242,
    E_TASK_PRI3 = 243,
    E_TASK_PRI4 = 244,
    E_TASK_PRI5 = 245,
    E_TASK_PRI6 = 246,
    E_TASK_PRI7 = 247,
    E_TASK_PRI8 = 248,
    E_TASK_PRI9 = 249,
    E_TASK_PRI10 = 250,
    E_TASK_PRI11 = 251,
    E_TASK_PRI12 = 252,
    E_TASK_PRI13 = 253,
    E_TASK_PRI14 = 254,
    E_TASK_PRI15 = 255,
} E_TASK_PRI;

// 任务状态（寄存器）
typedef struct REG
{
    U32             gs;
    U32             fs;
    U32             es;
    U32             ds;
    U32             edi;
    U32             esi;
    U32             ebp;
    U32             kesp;
    U32             ebx;
    U32             edx;
    U32             ecx;
    U32             eax;
    U32             eip;
    U32             cs;
    U32             eflags;
    U32             esp;
    U32             ss;
} REG;

// 任务
typedef struct TASK
{
    U32             id;                 // 任务 id
    U08*            name;               // 任务名称
    U08*            stack_addr;         // 任务栈基址
    U16             stack_size;         // 任务栈大小
    REG             reg;                // 任务上下文，即任务执行状态下所有寄存器的值
    TASK_FUNC       task_entry;         // 任务函数入口
    U08             priority;           // 优先级
    U32             current;            // 记录当前已执行的时间片数
    U32             total;              // 每次任务执行的总时间片数
} TASK;

typedef struct TASK_QUEUE_NODE
{
    QUEUE_NODE      QueueNode;
    TASK*           task;
} TASK_QUEUE_NODE;


extern volatile TASK*   current_task;           // 当前任务指针，永远指向当前任务
extern volatile U32     current_reg;            // 当前任务的上下文起始位置
extern QUEUE            TASK_READY_QUEUE;       // 就绪任务队列
extern QUEUE            TASK_WAIT_QUEUE;        // 等待任务队列
extern TASK_QUEUE_NODE  taskIdleQueueNode;      // 空闲任务队列节点

/******************************************************************************
* 函数名称: SwitchTo(TASK* task)
* 功能说明: 切换到任务 task 执行
* 输入参数: TASK*	task	--任务指针
* 输出参数: 无
* 函数返回: E_OK:成功; E_ERR:失败
* 其它说明: 无
******************************************************************************/
E_RET SwitchTo(TASK* task);

// 切换任务宏，其作用等同于 SwitchTo 函数
#define SWITCH_TO(t)    (void)({    \
    U32* pBase = (U32*)(&(t)->reg); \
    asm volatile(                   \
        "movl %0, %%esp\n"          \
        "popl %%gs\n"               \
        "popl %%fs\n"               \
        "popl %%es\n"               \
        "popl %%ds\n"               \
        "popal\n"                   \
        "iret\n"                    \
        :                           \
        : "r"(pBase)                \
        );}) 


/******************************************************************************
* 函数名称: E_RET TaskCreat(TASK* task, TASK_FUNC pFunc, U08* stackAddr, U16 stackSize, U08* name, E_TASK_PRI priority)
* 功能说明: 创建任务
* 输入参数: TASK_FUNC pFunc     --任务函数
    　　　　U08* stackAddr      --任务栈基址
    　　　　U16 stackSize       --任务栈大小
    　　　　U08* name           --任务名称
    　　　　E_TASK_PRI priority --任务优先级   
* 输出参数: TASK*	task        --任务指针
* 函数返回: E_OK:成功; E_ERR:失败
* 其它说明: 无
******************************************************************************/
E_RET TaskCreat(TASK* task, TASK_FUNC pFunc, U08* stackAddr, U16 stackSize, U08* name, E_TASK_PRI priority);

/******************************************************************************
* 函数名称: void TaskStart(void)
* 功能说明: 启动任务
* 输入参数: 无
* 输出参数: 无
* 函数返回: 无
* 其它说明: 想要启动所有任务，只要启动第一个任务就可以了，其它任务将由任务调度启动
******************************************************************************/
void TaskStart(void);

/******************************************************************************
* 函数名称: void TaskInit(void)
* 功能说明: 任务初始化
* 输入参数: 无
* 输出参数: 无
* 函数返回: 无
* 其它说明: 无
******************************************************************************/
void TaskInit(void);

/******************************************************************************
* 函数名称: void TaskDestory(void)
* 功能说明: 销毁当前任务
* 输入参数: 无
* 输出参数: 无
* 函数返回: 无
* 其它说明: 无
******************************************************************************/
E_RET TaskDestory(void);


#ifdef __cplusplus
}
#endif

#endif

